﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
using YArchitech.Revit;
using YArchitech.Revit.RevitExtension;

namespace HYCableTrayConnection
{
	internal class HYPlanarConnection
	{
		public bool NewPlanarConnection(IList<CableTray> cableTrays)
		{
			bool result = false;
			if (cableTrays.Count < 2)
			{
				throw new System.ArgumentNullException("CableTray", "is null");
			}
			Document document = cableTrays[0].Document;
			if (!Common.IsSameCableTrayType(document, cableTrays))
			{
				throw new MyException("桥架的类型不一致");
			}
			HYCableTray<CableTray> hycableTray = new HYCableTray<CableTray>(cableTrays[0]);
			HYCableTray<CableTray> hycableTray2 = new HYCableTray<CableTray>(cableTrays[1]);
			new List<CableTray>();
			if (!hycableTray.IsParallel(hycableTray2.CableTray))
			{
				throw new MyException("桥架必须平行");
			}
			bool flag = false;
			if (hycableTray.IsSamePlan(hycableTray2.CableTray))
			{
				flag = true;
			}
			double num = 0.0001;
			XYZ endXYZ = hycableTray2.EndXYZ;
			XYZ lineProject = hycableTray.GetLineProject(endXYZ);
			if (Math.Abs(endXYZ.X - lineProject.X) < num && Math.Abs(endXYZ.Y - lineProject.Y) < num)
			{
				flag = true;
			}
			if (!flag)
			{
				throw new MyException("请检查桥架位置");
			}
			IList<Connector> list = new List<Connector>();
			list = hycableTray.GetAppropriateConnector(cableTrays[1]);
			if (list[0] == null || list[1] == null || (list[0].IsConnected && list[1].IsConnected))
			{
				throw new MyException("桥架已经连接");
			}
			Transaction transaction = null;
			try
			{
				transaction = new Transaction(document, "Planar");
				transaction.Start();
				if (hycableTray.IsCableTrayOnLine(hycableTray2.CableTray) && hycableTray.CableTray.Width == hycableTray2.CableTray.Width && hycableTray.CableTray.Height == hycableTray2.CableTray.Height)
				{
					if (hycableTray.Combine(hycableTray2.CableTray))
					{
						result = true;
					}
				}
				else
				{
					double length = (endXYZ - new XYZ(lineProject.X, lineProject.Y, endXYZ.Z)).GetLength();
					double length2 = (endXYZ - new XYZ(endXYZ.X, endXYZ.Y, lineProject.Z)).GetLength();
					double num2 = (hycableTray.CableTray.Width + hycableTray2.CableTray.Width) / 2.0;
					double num3 = (hycableTray.CableTray.Height + hycableTray2.CableTray.Height) / 2.0;
					if (length <= num2 && length2 <= num3)
					{
						CableTrayFitingSel.GetCableTrayFittingType(document, CableTrayFittingType.Transition, hycableTray);
						if (document.Create.NewTransitionFitting(list[0], list[1]) != null)
						{
							result = true;
						}
					}
					else if (this.NewYZWFitting(document, hycableTray, hycableTray2))
					{
						result = true;
					}
				}
				transaction.Commit();
			}
			finally
			{
				if (transaction != null)
				{
					TransactionStatus status = transaction.GetStatus();
                    if ((int)status != 3 && (int)status != 2)
					{
						transaction.RollBack();
					}
				}
			}
			return result;
		}

		public bool NewYZWFitting(Document doc, HYCableTray<CableTray> myCustomCableTray, HYCableTray<CableTray> myCustomCableTray1)
		{
			IList<Connector> appropriateConnector = myCustomCableTray.GetAppropriateConnector(myCustomCableTray1.CableTray);
			HYCableTray<CableTray> hycableTray = this.CreateBranchTray(doc, myCustomCableTray, appropriateConnector);
			XYZ xyz = (appropriateConnector[0].Origin - appropriateConnector[1].Origin).Normalize();
			if (xyz.IsAlmostEqualTo(XYZ.BasisZ, 0.01) || xyz.IsAlmostEqualTo(-XYZ.BasisZ, 0.01))
			{
				Connector otherConnector = Common.GetOtherConnector(myCustomCableTray, appropriateConnector[0]);
				XYZ xyz2 = (appropriateConnector[0].Origin - otherConnector.Origin).Normalize();
				double angle = (-hycableTray.CustomConnectorStart.Connector.CoordinateSystem.BasisY).AngleOnPlaneTo(xyz2, XYZ.BasisZ);
				hycableTray.Rotate(angle);
			}
			try
			{
				this.TrayConnection(myCustomCableTray, myCustomCableTray1, hycableTray);
			}
			catch (Exception)
			{
				doc.DeleteElement(hycableTray.CableTray);
				try
				{
					Connector otherConnector2 = Common.GetOtherConnector(myCustomCableTray, appropriateConnector[0]);
					Connector otherConnector3 = Common.GetOtherConnector(myCustomCableTray1, appropriateConnector[1]);
					XYZ xyz3 = (appropriateConnector[0].Origin - otherConnector2.Origin).Normalize();
					XYZ xyz4 = (appropriateConnector[1].Origin - otherConnector3.Origin).Normalize();
					if (xyz3.IsAlmostEqualTo(xyz4, 0.01))
					{
						return false;
					}
					XYZ project = myCustomCableTray1.GetProject(appropriateConnector[0].Origin);
					if (project == null)
					{
						return false;
					}
					Connector connector = null;
					if (otherConnector3.IsConnected)
					{
						Connector connectConnector = this.GetConnectConnector(otherConnector3);
						connector = connectConnector;
						otherConnector3.DisconnectFrom(connectConnector);
					}
					Line curve = YJKLineEx.YJKGetBound(project, otherConnector3.Origin);
					(myCustomCableTray1.CableTray.Location as LocationCurve).Curve = curve;
					myCustomCableTray1 = new HYCableTray<CableTray>(myCustomCableTray1.CableTray);
					if (connector != null)
					{
						if (connector.Origin.IsAlmostEqualTo(myCustomCableTray1.CustomConnectorStart.XYZ, 0.01))
						{
							myCustomCableTray1.CustomConnectorStart.Connector.ConnectTo(connector);
						}
						else if (connector.Origin.IsAlmostEqualTo(myCustomCableTray1.CustomConnectorEnd.XYZ, 0.01))
						{
							myCustomCableTray1.CustomConnectorEnd.Connector.ConnectTo(connector);
						}
					}
					appropriateConnector = myCustomCableTray.GetAppropriateConnector(myCustomCableTray1.CableTray);
					hycableTray = this.CreateBranchTray(doc, myCustomCableTray, appropriateConnector);
					xyz = (appropriateConnector[0].Origin - appropriateConnector[1].Origin).Normalize();
					if (xyz.IsAlmostEqualTo(XYZ.BasisZ, 0.01) || xyz.IsAlmostEqualTo(-XYZ.BasisZ, 0.01))
					{
						double angle2 = (-hycableTray.CustomConnectorStart.Connector.CoordinateSystem.BasisY).AngleOnPlaneTo(xyz3, XYZ.BasisZ);
						hycableTray.Rotate(angle2);
					}
					this.TrayConnection(myCustomCableTray, myCustomCableTray1, hycableTray);
				}
				catch (Exception)
				{
					doc.DeleteElement(hycableTray.CableTray);
					return false;
				}
			}
			return true;
		}

		private void TrayConnection(HYCableTray<CableTray> myCustomCableTray, HYCableTray<CableTray> myCustomCableTray1, HYCableTray<CableTray> myCustomCableTray2)
		{
			HYCableTrayConnect hycableTrayConnect = new HYCableTrayConnect();
			IList<CableTray> list = new List<CableTray>();
			list.Add(myCustomCableTray.CableTray);
			list.Add(myCustomCableTray2.CableTray);
			hycableTrayConnect.NewElbowFittingByRevitCommand(list);
			list.Clear();
			list.Add(myCustomCableTray1.CableTray);
			list.Add(myCustomCableTray2.CableTray);
			hycableTrayConnect.NewElbowFittingByRevitCommand(list);
		}

		private HYCableTray<CableTray> CreateBranchTray(Document doc, HYCableTray<CableTray> myCustomCableTray, IList<Connector> connTwoDistanse)
		{
			if (connTwoDistanse != null && connTwoDistanse.Count > 1)
			{
				return new HYCableTray<CableTray>(this.NewCableTray(myCustomCableTray.CableTray, connTwoDistanse[0].Origin, connTwoDistanse[1].Origin));
			}
			throw new MyException("请检查桥架的位置");
		}

		private Connector GetConnectConnector(Connector connector)
		{
			Connector result = null;
			if (connector.IsConnected)
			{
				ConnectorSetIterator connectorSetIterator = connector.AllRefs.ForwardIterator();
				while (connectorSetIterator.MoveNext())
				{
					object obj = connectorSetIterator.Current;
					Connector connector2 = obj as Connector;
					if (connector2 != null && connector2.Owner.UniqueId != connector.Owner.UniqueId && ((int)connector2.ConnectorType == 1 || (int)connector2.ConnectorType == 2 || (int)connector2.ConnectorType == 19))
					{
						result = connector2;
						break;
					}
				}
			}
			return result;
		}

		private CableTray NewCableTray(CableTray sourceCableTray, XYZ startXYZ, XYZ endXYZ)
		{
			CableTray cableTray = null;
			if (sourceCableTray == null || startXYZ == null || endXYZ == null)
			{
				return null;
			}
			Document document = sourceCableTray.Document;
			foreach (ElementId elementId in ElementTransformUtils.CopyElement(document, sourceCableTray.Id, new XYZ(0.0, 0.0, 0.0)))
			{
				cableTray = (document.GetElement(elementId) as CableTray);
			}
			document.Regenerate();
			if (cableTray != null)
			{
				Line curve = Line.CreateBound(startXYZ, endXYZ);
				(cableTray.Location as LocationCurve).Curve = curve;
			}
			document.Regenerate();
			return cableTray;
		}
	}
}
